﻿// <copyright file="MultiScaleSubImage.Extensions.cs" company="Microsoft Corporation">
// Copyright (c) 2010 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Microsoft Live Labs</author>
// <email></email>
// <date>2010-05-15</date>
// <summary>MultiScaleSubImage extension methods</summary>

namespace Microsoft.LiveLabs.DeepZoom
{
    using System.Windows;
    using System.Windows.Controls;

    /// <summary>
    /// Extensions for the MultiScaleSubImage class
    /// </summary>
    public static class MultiScaleSubImageExtensions
    {
        #region Fields
        /// <summary>
        /// The origin dependency property
        /// </summary>
        public static readonly DependencyProperty OriginProperty = DependencyProperty.RegisterAttached(
            "Origin",
            typeof(Point),
            typeof(MultiScaleSubImage),
            new PropertyMetadata(new Point(), new PropertyChangedCallback(OriginChanged)));

        /// <summary>
        /// The Width dependency property
        /// </summary>
        public static readonly DependencyProperty WidthProperty = DependencyProperty.RegisterAttached("Width", typeof(double), typeof(MultiScaleSubImage), new PropertyMetadata(1.0, new PropertyChangedCallback(WidthChanged)));
        #endregion

        #region Methods
        /// <summary>
        /// Get the viewport bounds
        /// </summary>
        /// <param name="image">the multiscale sub image</param>
        /// <returns>the bounds</returns>
        public static Rect GetBounds(this MultiScaleSubImage image)
        {
            return new Rect(
                -image.ViewportOrigin.X / image.ViewportWidth,
                -image.ViewportOrigin.Y / image.ViewportWidth,
                (1 / image.ViewportWidth),
                (1 / image.ViewportWidth) / image.AspectRatio);
        }

        /// <summary>
        /// Set the bounds of the image
        /// </summary>
        /// <param name="image">the deep zoom image</param>
        /// <param name="bounds">the bounds to set the image to</param>
        public static void SetBounds(this MultiScaleSubImage image, Rect bounds)
        {
            image.ViewportOrigin = new Point(-bounds.X / bounds.Width, -bounds.Y / bounds.Width);
            image.ViewportWidth = 1 / bounds.Width;
        }

        /// <summary>
        /// Get the origin
        /// </summary>
        /// <param name="image">the multiscale image</param>
        /// <returns>the origin</returns>
        public static Point GetOrigin(this MultiScaleSubImage image) 
        { 
            return (Point)image.GetValue(OriginProperty); 
        }

        /// <summary>
        /// Set the origin
        /// </summary>
        /// <param name="image">the multi scale sub image</param>
        /// <param name="value">the origin</param>
        public static void SetOrigin(this MultiScaleSubImage image, Point value) 
        { 
            image.SetValue(OriginProperty, value); 
        }

        #endregion

        /// <summary>
        /// Origin changed event handler
        /// </summary>
        /// <param name="obj">the multi scale sub image</param>
        /// <param name="e">the dependency property changed event arguments</param>
        private static void OriginChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var image = obj as MultiScaleSubImage;
            Point origin = (Point)e.NewValue;
            double width = 1 / image.ViewportWidth;
            image.ViewportOrigin = new Point(
                -origin.X / width,
                -origin.Y / width);
        }

        /// <summary>
        /// Get the image width
        /// </summary>
        /// <param name="image">the multi scale image</param>
        /// <returns>the width in pixels</returns>
        public static double GetWidth(this MultiScaleSubImage image) 
        { 
            return (double)image.GetValue(WidthProperty); 
        }

        /// <summary>
        /// Set the image width
        /// </summary>
        /// <param name="image">the multi scale image</param>
        /// <param name="value">the width in pixels</param>
        public static void SetWidth(this MultiScaleSubImage image, double value) 
        { 
            image.SetValue(WidthProperty, value); 
        }

        /// <summary>
        /// Width changed event handler
        /// </summary>
        /// <param name="obj">the MultiScaleSubImage</param>
        /// <param name="e">the dependency property changed event arguments</param>
        private static void WidthChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            MultiScaleSubImage image = (MultiScaleSubImage)obj;
            double width = (double)e.NewValue;
            image.ViewportWidth = 1 / width;
        }
    }
}
